#include "../logs/log.h"
// 用户自定义扩展测试: 以时间进行滚动切换
//  滚动文件(文件写入时间-间隔)
namespace LOG
{
    class TRollSink : public LOG::LogSink
    {
    public:
        using ptr = std::shared_ptr<RollSink>;
        // 构造时传入文件名, 并且打开文件
        TRollSink(const std::string &basename) : _basename(basename), _name_cnt(0)
        {
            time_t t = util::Date::now();
            localtime_r(&t, &_last_time);
            std::string filename = createFilename();
            // 创建日志文件所在的目录
            util::File::createDirectory(util::File::path(filename));
            // 打开文件:二进制&&追加
            _ofs.open(filename, std::ios::binary | std::ios::app);
            assert(_ofs.is_open());
        }

        // 将日志消息写入标准输出--写入前判断文件写入时间, 时间间隔超出规定则切换文件
        void log(const char *data, size_t len)
        {
            time_t t = util::Date::now();
            tm cur_time;
            localtime_r(&t, &cur_time);
            if (cur_time.tm_sec - _last_time.tm_sec >= 4) // 每四秒切换一个文件
            {
                _ofs.close(); // 先把原来的文件关闭掉
                std::string filename = createFilename();
                _last_time = cur_time;
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.is_open());
            }
            _ofs.write(data, len);
            assert(_ofs.good());
        }

    private:
        void initLogFile()
        {
        }
        // 进行时间判断, 不符合规则就创建新文件
        std::string createFilename()
        {
            // 获取系统时间: 基础文件名字+扩展文件名
            // 202522-12:42:52.log
            time_t t = util::Date::now();
            struct tm lt;
            localtime_r(&t, &lt);
            std::stringstream ss;
            ss << _basename;
            ss << lt.tm_year + 1900;
            ss << lt.tm_mon + 1;
            ss << lt.tm_mday;
            ss << "-";
            ss << lt.tm_hour;
            ss << ":";
            ss << lt.tm_min;
            ss << ":";
            ss << lt.tm_sec;
            ss << "-";
            ss << _name_cnt++;
            ss << ".log";
            return ss.str();
        }

    private:
        // 输出文件名=基础文件名+扩展文件名
        int _name_cnt;
        std::string _basename; // 滚动文件的基础名字 ./logs/base-时间戳
        std::ofstream _ofs;    // 对文件进行操作
        tm _last_time;         // 上一次文件写入的时间
    };
}

int main()
{

    LOG::Formatter::ptr fmt(new LOG::Formatter()); // 对象实例化

    // 通过建造者模式来搭建日志器
    std::unique_ptr<LOG::LoggerBuilder> builder(new LOG::GlobalLoggerBuilder());
    builder->buildLoggerLevel(LOG::LogLevel::value::INFO);
    builder->buildLoggerName("async_root");
    builder->buildLoggerFormat(fmt);
    builder->buildLoggerType(LOG::LoggerType::LOGGER_ASYNC);
    builder->buildEnableUnSafeAsync();
    builder->buildSink<LOG::StdoutSink>();
    // builder->buildSink<LOG::FileSink>("./log_test/async.log");
    builder->buildSink<LOG::TRollSink>("./log_roll/tm-log-");
    LOG::Logger::ptr logger = builder->build();

    int cnt = 0;
    while (cnt <= 10)
    {
        logger->info("测试扩展模块%d", cnt++);
        sleep(1);
    }

    return 0;
}
